﻿using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Red.Controls.DataDriven;
using Red.Controls.Extensions;
using Red.Controls.ViewModels;

namespace Red.Controls
{
    public class DataInterceptionEventArgs : RoutedEventArgs
    {
        /// <summary>
        ///     Intercepted data to be modified
        /// </summary>
        public IDataObject Data { get; set; }

        /// <summary>
        ///     This object returns promise as Task<IDataObject> and sets its result
        /// </summary>
        public TaskCompletionSource<IDataObject> Tcs { get; private set; }

        public DataInterceptionEventArgs( RoutedEvent routedEvent, object source )
            : base( routedEvent, source )
        {
            Tcs = new TaskCompletionSource<IDataObject>();
        }
    }

    /// <summary>
    /// Interaction logic for ObjectsPaletteItem.xaml
    /// </summary>
    [InteropControl( "ObjectsPaletteItem" )]
    public partial class ObjectsPaletteItemView : UserControl
    {
        #region DataInterception

        /// <summary>
        ///     Event used to modify object's drag data on the fly
        /// </summary>
        public static readonly RoutedEvent DataInterceptionEvent =
            EventManager.RegisterRoutedEvent( "DataInterception",
                RoutingStrategy.Bubble, typeof( DataInterceptionEventHandler ), typeof( ObjectsPaletteItemView ) );

        public delegate void DataInterceptionEventHandler( object sender, DataInterceptionEventArgs e );

        public static void AddDataInterceptionHandler( DependencyObject obj, DataInterceptionEventHandler handler )
        {
            var element = obj as FrameworkElement;
            if ( element != null )
            {
                element.AddHandler( DataInterceptionEvent, handler );
            }
        }

        #endregion DataInterception

        public static void RemoveDataInterceptionHandler( DependencyObject obj, DataInterceptionEventHandler handler )
        {
            var element = obj as FrameworkElement;
            if ( element != null )
            {
                element.RemoveHandler( DataInterceptionEvent, handler );
            }
        }

        public ObjectsPaletteItemView()
        {
            InitializeComponent();
        }

        private void Item_DragStart( object sender, DragStartEventArgs e )
        {
            var element = sender as FrameworkElement;

            var dataItem = DataContext as ObjectsPaletteItem;
            if ( dataItem != null )
            {
                var args = new DataInterceptionEventArgs( DataInterceptionEvent, sender );
                args.Data = dataItem.GetDraggedData();
                e.DraggedData = args.Tcs.Task;
                element.RaiseEvent( args );
            }
        }
    }
}
